<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
	/**
	 * CodeIgniter
	 *
	 * An open source application development framework for PHP 4.3.2 or newer
	 *
	 * @package		CodeIgniter
	 * @author		ExpressionEngine Dev Team
	 * @copyright	Copyright (c) 2008 - 2009, EllisLab, Inc.
	 * @license		http://codeigniter.com/user_guide/license.html
	 * @link		http://codeigniter.com
	 * @since		Version 1.0
	 * @filesource
	 */
	// ------------------------------------------------------------------------
	
	/**
	 * @package		CodeIgniter
	 * @subpackage	Libraries
	 * @author		AnhDT
	 */
	 
	require_once APP_LIBRARY_PATH . 'html/tag/interfaces/st_interface_tag.php';
	
	class st_tag_event_handler {
		/**Đối tượng đăng ký bộ xử lý sự kiện*/
		protected $_sender   = NULL;
		/**Tên sự kiện được đăng ký*/
		protected $_event    = ''; 
		/**Bộ xử lý sự kiện trên phần server: callback và trên phần client: javascript*/
		protected $_handler  = array(
							  	 'callback'   => array(),
								 'javascript' => array(),
							   );
		/**Chỉ khi đối tượng đăng ký sự kiện kích hoạt sự kiện thì bộ xử lý sự kiện được kích hoạt*/
		protected $_isActived = false;
		
		function __construct(st_interface_tag $_sender = null, $_event = '') {
			if (null !== $_sender) {
				$this->_sender = & $_sender;
			}
			if (!empty($_event)) {
				$this->_event  = $_event;
			}
		}
		
		/** Thiết lập tên sự kiện được đăng ký*/
		public function setEvent($_eventName = '') {
			if (!is_string($_eventName) || empty($_eventName)) {
				return false;	
			}	
			$this->_event = $_eventName;
			return $this;
		}
		
		/** Lấy về tên sự kiện được đăng ký*/
		public function & getEvent() {
			return $this->_event;	
		}
		
		/** Lấy về tên các sự kiện được sử lý ở phần server*/
		public function & getCallbackHandlers() {
			return (array)$this->_handler['callback'];
		}
		
		/** Lấy về tên các sự kiện được sử lý ở phần client*/
		public function & getJsHandlers() {
			$_handlers = (array)$this->_handler['javascript'];
			return $_handlers;
		}
		
		/** Thêm sự kiện được sử lý ở phần server*/
		public function addCallbackHandler($_handler) {
			if (!is_string($_handler) || empty($_handler)) {
				return false;	
			}
			if (empty($_handlerId) || !is_string($_handlerId)) {
				$_handlerId = $_handler;	
			}
			$this->_handler['callback'][$_handlerId] = $_handler;
			return $this;
		}
		
		/** Xóa sự kiện được sử lý ở phần server theo mã xử lý sự kiện*/
		public function removeCallbackHandler($_handlerId = '') {
			if (!is_string($_handlerId) || empty($_handlerId) || !isset($this->_handler['callback'][$_handlerId])) {
				return false;	
			}
			unset($this->_handler['callback'][$_handlerId]);
			return $this;
		}
		
		/** Xóa sự kiện được sử lý ở phần client theo mã xử lý sự kiện*/
		protected function removeJsHandler($_handlerId = '') {
			if (!is_string($_handlerId) || empty($_handlerId) || !isset($this->_handler['javascript'][$_handlerId])) {
				return false;	
			}
			unset($this->_handler['javascript'][$_handlerId]);
			return $this;
		}
		
		/** Thêm sự kiện được sử lý ở phần client*/
		public function addJsHandler($_handlerId = '', $_handler = '') {
			if (!is_string($_handler) || empty($_handler)) {
				return false;	
			}
			if (empty($_handlerId) || !is_string($_handlerId)) {
				$_handlerId = $_handler;	
			}
			$this->_handler['javascript'][$_handlerId] = $_handler;
			return $this;
		}
		
		/**Reset lại thông tin của bộ xử lý sự kiện*/
		public function reset() {
			$this->_sender = null;
			$this->resetCallbackHandlers();
			$this->resetJsHandlers();
			$this->isActive = false;
		}
		
		/**Reset lại các xử lý sự kiện ở phần server*/
		public function resetCallbackHandlers() {
			$this->_handler['callback'] = array();
			return $this;
		}
		
		/**Reset lại các xử lý sự kiện ở phần client*/
		public function resetJsHandlers() {
			$this->_handler['javascript'] = array();
			return $this;
		}
		
		/**Gắn kết đối tượng với bộ xử lý sự kiện*/
		public function setObjectBinding($_sender = NULL) {
			if (NULL !== $_sender && $_sender instanceof st_interface_tag) {
				$this->_sender = & $_sender;
			}
			return $this;
		}
		
		/**
		Xuất ra định dạng mã javascript, vd: alert("tester"); document.write("Tested Document");
		*/
		public function toJsString() {
			return implode('; ', $this->getJsHandlers());	
		}
		
		/**Trước khi xuất ra sự kiện, xử lý các phương thức được gắn liền với sự
		* kiện của thẻ
		*/
		public function activeEventMethods() {
			$_methods = get_class_methods($this);
			/**Thực thi những phương thức có hậu tố là Event, vd: changeNameEvent*/
			foreach ($_methods as $_method) {
				if (preg_match('/^.*Event$/', $_method, $_matched)) {
					$this->$_matched[0]();	
				}	
			}
			/**Các xử lý sự kiện đã được thực thi*/
			$this->_isActived = true;
			return $this;
		}
		
		/**Kiểm tra sự kiện đã được kích hoạt hay chưa*/
		public function isActive() {
			return $this->_isActived;	
		}
		
		/**Lấy về đối tượng đã đăng ký sự kiện*/
		public function getSender() {
			if ($this->hasObjectBinding()) {
				return false;	
			}	
			return $this->_sender;
		}
		
		/**Alias của phương thức getSender*/
		public function getObjectBinding() {
			return $this->getSender();	
		}
		
		/**Kiểm tra bộ xử lý sự kiện đã gắn kết với một đối tượng nào chưa*/
		public function hasObjectBinding() {
			if (!empty($this->_sender) && $this->_sender instanceof st_tag_abstract) {
				return true;	
			}	
			return false;
		}
	}
?>